//888888888888888888888888888888888888888888888888888888888888888888888888888888888888888
//
//	File		 :	glob_files.cpp
//	Contents	 :	source file for globbing
//	Creation Date:	19/01/2005
//	tabs width	 :	every 4 characters
//
//888888888888888888888888888888888888888888888888888888888888888888888888888888888888888
//#include "perlutil.h"
#include "glob_files.h"
#include <glob.h>
#include <stdexcept>
#include <set>
//#include <algorithm>
#include <boost/algorithm/string/split.hpp>
#include "is_equal_to.h"
//#include "stlhelper.h"
#include <set>
	using std::set;
#include <vector>
	using std::vector;
#include <string>
	using std::string;
#include <boost/range/algorithm/sort.hpp>
	using boost::sort;
#include <boost/range/algorithm/unique.hpp>
	using boost::unique;
#include <boost/range/algorithm_ext/erase.hpp>
	using boost::erase;
#include <boost/range/algorithm_ext/push_back.hpp>
	using boost::push_back;


namespace glob_files
{
vector<string> glob(const string& path)
{
	vector<string> matches;
	glob_t glob_data;
	int glob_res = glob(path.c_str(), 0, 0, &glob_data);
	if (glob_res == GLOB_NOSPACE)
		throw std::runtime_error("Memory allocation failed when enumerating "
											"files for [" + path + "]");

    for (unsigned i = 0; i < glob_data.gl_pathc; ++i)
		matches.push_back(glob_data.gl_pathv[i]);
	globfree(&glob_data);
	return matches;
}

std::vector<std::string>  glob_expand(const std::vector<std::string>& paths)
{
	set<string> expanded_paths;
	for (unsigned ii = 0; ii < paths.size(); ++ii)
	{
		vector<string> globbed_paths = glob(paths[ii]);
		expanded_paths.insert(globbed_paths.begin(), globbed_paths.end());
	}

	// sort and remove duplicates
	vector<string> results(expanded_paths.begin(), expanded_paths.end());
	return erase(results, unique<boost::return_found_end>(sort(results)));
}


vector<string>  glob_all(const vector<string>& input_paths)
{
	vector<string> matches;

	// get all files
	vector<string> split_paths;
	for (unsigned i = 0; i < input_paths.size(); ++i)
	{
		vector<string> paths;
		boost::algorithm::split( paths, input_paths[i], is_equal_to('\t'));
		//perlutil::perl_split (input_paths[i], " \t", perlutil::eIGNORE_EMPTY, paths);
		split_paths.insert(split_paths.end(),  paths.begin(), paths.end());
	}
	for (unsigned i = 0; i < split_paths.size(); ++i)
		push_back(matches, glob(split_paths[i]));

	// sort and remove duplicates
	return erase(matches, unique<boost::return_found_end>(sort(matches)));
}


}

